// Objects class
// Martin Dorazil Feb 32 2013

#pragma once

#ifdef _WIN32 
#include <windows.h> 
#include "SDL_thread.h"
#else
#include "SDL/SDL_thread.h"
#endif

#include "Entity.h"
#include "static/vegetation/Tree.h"
#include "static/vegetation/Grass.h"
#include "Entity.h"
#include "dynamic/villager/Villager.h"
#include "static/building/Building.h"
#include "dynamic/villager/Gatherer.h"
#include "dynamic/animal/Deer.h"
#include "static/building/BLumberjack.h"
#include "static/building/BHunter.h"
#include "dynamic/villager/Hunter.h"
#include "dynamic/villager/Taxman.h"
#include "dynamic/villager/Builder.h"
#include "static/building/BBuilder.h"
#include "static/building/BBank.h"

#include <vector>
#include <glm/glm.hpp>

#include "../octree/Box.h".

#include "../models/ModelPool.h"
#include "../mechanics/PathFinder.h"
#include "../Terrain.h"

namespace Objects
{

const float BOUNDING_BOX_OFFSET = 2.0;

class Objects
{
public:
	Objects(ModelPool *_mPool, PathFinder *_pathfinder, Octree::Box *_Octree,
			Terrain::Terrain *_ter);
	virtual ~Objects(void);

	void control(float t);

	// draw all entities, input shader type
	// shadow parameter when first pass drawing
	// normal parameter for normal draw whit its own shader
	void drawEntities(int shaderType);
	// draw only boundding box of entities
	void drawEntBBox();

	// inserting entities section
	// every method returns pointer to new object
	Grass* insertGrass(glm::vec3 _Pos, // entity position
			float _r, // angle
			std::string _Name, // name of entity
			std::string _modelFName // name of model in pool
			);// inserting entity to map

	Tree* insertTree(glm::vec3 _Pos, // entity position
			float _r, // angle
			std::string _Name, // name of entity
			std::string _modelFName, // name of model in pool
			float age); // inserting entity to map

	Entity* insertBuilding(glm::vec3 _Pos, // entity position
			float _r, // angle
			std::string _Name, // name of entity
			std::string _modelFName, // name of model in pool
			float age, int type, int status); // inserting entity to map

	Villager* insertVillager(glm::vec2 _Pos, // entity position
			float _r, // angle
			std::string _Name, // name of entity
			std::string _modelFName, // name of model in pool
			int type, int status); // inserting entity to map

	Deer* insertDeer(glm::vec3 _Pos, // entity position
			float _r, // angle
			std::string _Name, // name of entity
			std::string _modelFName // name of model in pool
			);// inserting entity to map
	//-------------------------------------------------------------------------

	// delete section
	void deleteAllEnt(); // delete all entities

	unsigned int getMovingCount();
	unsigned int getEntityCount();

	std::vector<Entity*> getEntity();
	std::vector<Entity*> getMentity();

	void setOctree(Octree::Box *b);
private:
	Octree::Box *Octree;
	ModelPool *mPool;
	PathFinder *pathfinder;
	Terrain::Terrain *ter;

	// Entities on map
	std::vector<Entity*> entity;

	//mooving entities only id to entity
	std::vector<Entity*> mentity;

};

}

